(defpackage :numberpad
  (:use :cl)
  (:nicknames :np)
  (:export :read-number
           :numberpad
           :operatorpad))

(in-package :numberpad)

(defclass num (gwee:text-area)
  ((str :initform nil :initarg :string :accessor str))
  (:default-initargs
   :font (gwee:open-font gwee:*default-font-name* 16)
   :width :maximum
     :horizontal-justification :center
     :vertical-justification :center))

(gwee:define-component numberpad ()
  ((callback :initarg :callback :accessor callback))
  (:views
   (n1 num :data "1")
   (n2 num :data "2")
   (n3 num :data "3")
   (n4 num :data "4")
   (n5 num :data "5")
   (n6 num :data "6")
   (n7 num :data "7")
   (n8 num :data "8")
   (n9 num :data "9")
   (n0 num :data "0")
   (pivot num :data (string (code-char #x00BB)) :string :pivot))
  (:layouts
   (default gwee:column-layout
       (n1 n2 n3 n4 n5 pivot n6 n7 n8 n9 n0)
     :border-color gwee:*default-foreground-color*
     :margin 1
     :padding 0))
  (:default-initargs
      :width 25 :height 193))

(gwee:define-component operatorpad ()
  ((callback :initarg :callback :accessor callback))
  (:views
   (divide num :data (string (code-char 247)) :string "/")
   (times num :data (string (code-char 215)) :string "*")
   (plus num :data "+")
   (minus num :data "-";;  (string (code-char 8722))
          :string "-")
;;    (fraction num :data "/")
   (pivot num :data (string (code-char #x00BB)) :string :pivot))
  (:layouts
   (default gwee:column-layout
       (divide times pivot plus minus)
     :border-color gwee:*default-foreground-color*
     :margin 1
     :padding 0))
  (:default-initargs
      :width 25 :height 91))

(defmethod gwee:mouse-press-event ((view num) button x y)
  (let ((comp (gwee:component-for-view view)))
    (when (callback comp)
      (funcall (callback comp) (or (str view)
                                   (gwee:view-data view))))
    (gwee:delete-view comp)
    t))

(defun enter-hook (v state)
  (psetf (gwee:background-color v) gwee:*default-foreground-color*
         (gwee:foreground-color v) gwee:*default-background-color*
         (gwee:view-needs-update-p v) t))

(defun leave-hook (v state)
  (psetf (gwee:background-color v) gwee:*default-background-color*
         (gwee:foreground-color v) gwee:*default-foreground-color*
         (gwee:view-needs-update-p v) t))

(defmethod shared-initialize :after ((obj num) slot-names &key)
  (gwee:add-hook (gwee:enter-hook obj) 'enter-hook)
  (gwee:add-hook (gwee:leave-hook obj) 'leave-hook))

(defun read-number (view x y &key (class 'numberpad) callback)
  (let ((pad (make-instance class
                            :callback (lambda (s)
                                        (sdl-cffi::sdl-warp-mouse (gwee:view-to-top-x view x) (gwee:view-to-top-y view y))
                                        (funcall callback s))
                            :parent view
                            :x x :y y)))
    (setf (gwee:view-x pad) (- (gwee:view-x pad)
                               (truncate (gwee:view-width pad) 2))
          (gwee:view-y pad) (min (- (gwee:view-y pad)
                                    (truncate (gwee:view-height pad) 2))
                                 (- (gwee:view-height view)
                                    (gwee:view-height pad)
                                    2))
          (gwee:view-needs-update-p pad) t)
    pad))
